<?php
/**
 * Holds class Image_RLE
 *
 * @author daantimmer
 *
 * @package Library
 * @subpackage Image
 */
class Image_RLE{
	
	/**
	 * @var Image_Lib_LookUp
	 */
	private $lut;
	
	private $x, $y, $count;
	
	/**
	 * @var Image_RLEObj
	 */
	private $currObj;
	
	private $bucket = array();
	
	public function __construct(Image_Lib_LookUp $lut){
		$this->lut = $lut;
	}
	
	public function createRLE(Image_Image $img, Image_GetFactory $get){
		$this->x = $this->y = $this->count = 0;;
		$bucket = array();
		
		$rle = new ArrayList();
		$prev = $this->next($img,$get);
		
		while($this->bounds($img)){
			$curr = $this->next($img,$get);
			if($curr->getIndex() == $prev->getIndex()){
				$prev->incr();
			}else{
				$rle->add($prev);
				
				if(isset($bucket[$prev->getIndex()]))
					$bucket[$prev->getIndex()] += $prev->length();
				else
					$bucket[$prev->getIndex()] = $prev->length();
				
				$prev = $curr;
			}
		}
		
		if(isset($bucket[$prev->getIndex()]))
			$bucket[$prev->getIndex()] += $prev->length();
		else
			$bucket[$prev->getIndex()] = $prev->length();
		
		$rle->add($prev);
		
		$minsize = ($img->getWidth()*$img->getHeight());
		
		if(isset($bucket[$i = Image_ColorIndex::instance()->NONE]))
			$minsize -= $bucket[$i];
		
		if(isset($bucket[$i = Image_ColorIndex::instance()->WHITE]))
			$minsize -= $bucket[$i];
		
		$minsize *= 0.33;

		
		var_dump($minsize,$bucket);
		
		$rlen = new ArrayList();
		do{
			$rle->remove($enc = $rle->getFirst());
			
			if($bucket[$enc->getIndex()] < $minsize){
				$enc->setIndex(Image_ColorIndex::instance()->NONE);
//				$enc->setColor(new Image_Lib_Color(0));
			}
			$rlen->add($enc);
			
		}while(!$rle->isEmpty());
		
//		foreach($rle AS $key => $enc){
//			if($bucket[$enc->getIndex()] < $minsize){
//				$enc->setIndex(Image_ColorIndex::instance()->NONE);
//			}
//		}
		
		return $rlen;
	}
	
	private function bounds(Image_Image $img){
		if($this->y >= $img->getHeight()) return false;
		return true;
	}
	
	/**
	 * @param Image_Image $img
	 * @param Image_GetFactory $get
	 * @return Image_RLEObj
	 */
	private function next(Image_Image $img, Image_GetFactory $get){
		$col = $get->get($this->x++,$this->y,$img);
		
		if($this->x >= $img->getWidth()){
			$this->x = 0;
			$this->y++;
		}
		
		return $this->lut->lookUp($col);
	}
	
	public function rle2image($width, $height, ArrayList $_rle){
		$img = new Image_Image($width,$height);
		$this->x = $this->y = 0;
		
		$rle = clone $_rle;
		
		$col = $this->getNextRLEColor($rle);
		
		do{
			$this->putNextColor($img, $col);
			$col = $this->getNextRLEColor($rle);
		}while($col != null);
		
		return $img;
	}
	
	private function getNextRLEColor(ArrayList $rle){
		if($rle->isEmpty() && $this->count == 0)
			return null;
		
		if($this->currObj == null || $this->count == 0){
			$rle->remove($this->currObj = $rle->getFirst());
			$this->count = $this->currObj->length();
		}
		$this->count--;
		
		return $this->currObj->color();
	}
	
	private function putNextColor(Image_Image $img, Image_Lib_Color $col){
		$img->setColor($this->x++,$this->y,$col);
	
		if($this->x >= $img->getWidth()){
			$this->x = 0;
			$this->y++;
		}
	}
}